﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using AccessControl.Business;
using AccessControl.Common;
using AccessControl.FingerPrintEngine.Properties;
using AccessControl.FingerPrintLibrary;
using AccessControl.Utility.Tools;


namespace AccessControl.FingerPrintEngine
{
    public class FingerPrintEngine
    {
        #region Settings

        private static int MinRank
        {
            get
            {
                return Settings.Default.MinRank;
            }
        }

        private static int MaxRank
        {
            get
            {
                return Settings.Default.MaxRank;
            }
        }

        private static bool CheckSecondFingerPrint
        {
            get
            {
                return
                    Settings.Default.CheckSecondFingerPrint;
            }
        }

        private static bool FilterByG
        {
            get
            {
                return Settings.Default.FilterByG;
            }
        }

        private static byte GOffset
        {
            get
            {
                return Settings.Default.GOffset;
            }
        }

        #endregion

        #region Fields

        private static FingerPrintEngine _fingerPrintEngine;
        private static bool _initialized;
        private AccessControlDS.tblFingerTemplateDataTable _tblFingerTemplateDataTable;
        private AccessControlDS.tblPersonEventDataTable _tblPersonEventDataTable;
        private AccessControlDS.tblEventDataTable _tblEventDataTable;

        private static Dictionary<String, PersonFingerTemplate> _personFingerTemplatesDic;
        private static Dictionary<Int32, List<String>> _eventPersonDic;

        private static ArrayList[] _fingersArray;

        #endregion

        #region Constructor & Singletone

        private FingerPrintEngine()
        {
            if (!_initialized) Initialize();
        }

        public static FingerPrintEngine GetInstance()
        {
            return _fingerPrintEngine ?? (_fingerPrintEngine = new FingerPrintEngine());
        }

        #endregion

        #region Public Method

        private void Initialize()
        {
            _tblFingerTemplateDataTable = FingerTemplateBusiness.SelectAll();
            _tblPersonEventDataTable = PersonEventBuisness.SelectAll();
            _tblEventDataTable = EventBusiness.SelectAll();

            LoadFingerTemplatesDic();
            LoadFingerTemplateArray();
            LoadPesonEventDic();

            _initialized = true;

        }

        public bool EnrollPersonFinger(String pkPerson, Byte fingerIndex, Byte[][] rawImage, out String errorMessage)
        {
            string error=null;

            try
            {
                if (!((Match(rawImage[0], rawImage[1], out  error)) && (Match(rawImage[0], rawImage[2], out  error))))
                {
                    WriteLog("Fingers are not equal for person " + pkPerson, "EnrollPersonFinger", eventLevelConstants.Warning);
                    errorMessage = "3 Fingers are not equal";
                    return false;
                }

                int g;
                var template = Extraction.GetInstance().Generalize(rawImage, out g, out error);
                errorMessage = error;
                if (error != null){
                    WriteLog("Generalize Error "+error+" for person " + pkPerson, "EnrollPersonFinger", eventLevelConstants.Warning);
                    return false;
                }
                var fingerPrintTemplateTable = new AccessControlDS.tblFingerTemplateDataTable();
                var fingerPrintRow = fingerPrintTemplateTable.NewtblFingerTemplateRow();
                fingerPrintRow.fkPerson = pkPerson;
                fingerPrintRow.TemplateFinger = fingerIndex;
                fingerPrintRow.Template = template;
                fingerPrintRow.TemplateG = g;
                fingerPrintRow.TemplateHash = 0;
                fingerPrintRow.TemplateSize = template.Length;
                fingerPrintRow.UpdateDate = DateTime.Now;
                if (FingerTemplateBusiness.CheckIfFingerExist(pkPerson, fingerIndex))

                    FingerTemplateBusiness.Update(fingerPrintRow);

                else
                    FingerTemplateBusiness.Insert(fingerPrintRow);
                UpdateFingersArray(pkPerson, fingerIndex, template, g);
                //UpdatFingerTemplatesDic(pkPerson, fingerIndex, template, g);
                return true;
            }
            catch (Exception ex)
            {
                WriteLog(error, "EnrollPersonFinger", eventLevelConstants.Warning);
                WriteLog(ex.Message, "EnrollPersonFinger", eventLevelConstants.Error);
                errorMessage = error;
                return false;
            }
        }

        public string IdentifyPerson(Byte[] rawImage, Int32 pkEvent, out String errorMessage)
        {
            var learner = new Learner();
            var error1 = String.Empty;
            var topRank = 0;
            var pkMatchedPerson = String.Empty;
            try
            {
                int g;
                byte[] newTemlpate = Extraction.GetInstance().ExtractToByte(rawImage, out g, out error1);
                errorMessage = error1;
                if (newTemlpate == null)
                    return string.Empty;
                var matcher = Verification.GetFingerMatcherInstance();
                if (_eventPersonDic.Count() == 0)
                    return String.Empty;
                var personList = _eventPersonDic[pkEvent];
                matcher.IdentifyStart(newTemlpate);

                IEnumerable<PersonFingerTemplate>
                    templateList;

                if (FilterByG)
                    templateList = _personFingerTemplatesDic.Values.Where(
                        row => ((row.G1 >= g - GOffset) && (row.G1 <= g + GOffset)) || ((row.G2 >= g - GOffset) && (row.G2 <= g + GOffset)));
                else
                    templateList = _personFingerTemplatesDic.Values;

                foreach (var template in templateList)
                {
                    if (!personList.Contains(template.PkPerson))
                        continue;

                    if (template.Template1 == null)
                        continue;
                    var rank = matcher.IdentifyNext(template.Template1);
                    if ((rank <= 0) || (rank <= topRank))
                        continue;
                    pkMatchedPerson = template.PkPerson;
                    topRank = rank;

                    learner.FkPerson = pkMatchedPerson;
                    learner.FingerIndex = 1;
                    learner.NewTemplate = newTemlpate;
                    learner.ExistingTemplate = template.Template1;

                    if (topRank >= MaxRank)
                        break;
                }

                if ((topRank < MinRank) && (CheckSecondFingerPrint))
                {
                    foreach (var template in _personFingerTemplatesDic.Values)
                    {
                        if (!personList.Contains(template.PkPerson))
                            continue;

                        if (template.Template2 == null)
                            continue;
                        var rank = matcher.IdentifyNext(template.Template2);
                        if ((rank <= 0) || (rank <= topRank))
                            continue;
                        pkMatchedPerson = template.PkPerson;
                        topRank = rank;

                        learner.FkPerson = pkMatchedPerson;
                        learner.FingerIndex = 1;
                        learner.NewTemplate = newTemlpate;
                        learner.ExistingTemplate = template.Template1;

                        if (topRank >= MaxRank)
                            break;
                    }
                }
                matcher.IdentifyEnd();

                if (topRank > MinRank && topRank < MaxRank)
                {
                    ThreadPool.QueueUserWorkItem(learner.Generalize);
                }

            }
            catch (Exception ex)
            {
                WriteLog(error1, "IdentifyPersonByEvent", eventLevelConstants.Warning);
                WriteLog(ex.Message, "IdentifyPersonByEvent", eventLevelConstants.Error);
                errorMessage = error1;
                return String.Empty;
            }


            return topRank >= MinRank ? pkMatchedPerson : String.Empty;
        }

        public string IdentifyPerson(Byte[] rawImage, out String errorMessage)
        {
            var generalizer = new Learner();

            var error = String.Empty;
            FingerMatcher matcher;
            var topRank = 0;
            var pkMatchedPerson = String.Empty;
            try
            {
                int g;
                var newTemlpate = Extraction.GetInstance().ExtractToByte(rawImage, out g, out error);
                errorMessage = error;
                if (newTemlpate == null)
                    return string.Empty;
                matcher = Verification.GetFingerMatcherInstance();
                matcher.IdentifyStart(newTemlpate);
                IEnumerable<PersonFingerTemplate>
                 templateList;
                if (FilterByG)
                    templateList = _personFingerTemplatesDic.Values.Where(
                         row => ((row.G1 >= g - GOffset) && (row.G1 <= g + GOffset)) || ((row.G2 >= g - GOffset) && (row.G2 <= g + GOffset)));
                else
                    templateList = _personFingerTemplatesDic.Values;

                foreach (var template in templateList)
                {
                    if (template.Template1 == null)
                        continue;
                    var rank = matcher.IdentifyNext(template.Template1);
                    if ((rank <= 0) || (rank <= topRank))
                        continue;
                    pkMatchedPerson = template.PkPerson;
                    topRank = rank;

                    generalizer.FkPerson = pkMatchedPerson;
                    generalizer.FingerIndex = 1;
                    generalizer.NewTemplate = newTemlpate;
                    generalizer.ExistingTemplate = template.Template1;

                    if (topRank >= MaxRank)
                        break;
                }
                if ((topRank < MinRank) && (CheckSecondFingerPrint))
                {
                    foreach (var template in _personFingerTemplatesDic.Values)
                    {
                        if (template.Template2 == null)
                            continue;
                        var rank = matcher.IdentifyNext(template.Template2);
                        if ((rank <= 0) || (rank <= topRank))
                            continue;
                        pkMatchedPerson = template.PkPerson;
                        topRank = rank;

                        generalizer.FkPerson = pkMatchedPerson;
                        generalizer.FingerIndex = 2;
                        generalizer.NewTemplate = newTemlpate;
                        generalizer.ExistingTemplate = template.Template2;

                        if (topRank >= MaxRank)
                            break;
                    }
                }
                matcher.IdentifyEnd();

                if (topRank > MinRank && topRank < MaxRank)
                {
                    ThreadPool.QueueUserWorkItem(generalizer.Generalize);
                }

                //if (topRank == 0)
                //    SaveToFile(rawImage, "C:\\AccessControlLog\\Images3\\" + Environment.TickCount + ".bmp");
                //else
                //    SaveToFile(rawImage, "C:\\AccessControlLog\\Images3\\S_" + pkMatchedPerson + "_" + Environment.TickCount + "_" + topRank + ".bmp");

            }
            catch (Exception ex)
            {
                WriteLog(error, "IdentifyPerson", eventLevelConstants.Warning);
                WriteLog(ex.Message, "IdentifyPerson", eventLevelConstants.Error);
                errorMessage = error;
                return String.Empty;
            }


            return topRank >= MinRank ? pkMatchedPerson : string.Empty;
        }

        public string IdentifyPersonByG(Byte[] rawImage, out String errorMessage){
            var t = Environment.TickCount;
            var generalizer = new Learner();
            var error = String.Empty;
            FingerMatcher matcher;
            var topRank = 0;
            var pkMatchedPerson = String.Empty;
            var matchedG = 0;
            try
            {
                int g;
                var baseTemlpate = Extraction.GetInstance().ExtractToByte(rawImage, out g, out error);
                errorMessage = error;
                if (baseTemlpate == null)
                    return string.Empty;
                matcher = Verification.GetFingerMatcherInstance();
                matcher.IdentifyStart(baseTemlpate);
                var i = 0;
                do
                {
                    int tmpTopRank;
                    if (i == 0)
                    {
                        if (_fingersArray[g] == null)
                        {
                            i++;
                            continue;
                        }

                        FingerTemplate fingerTemplate;
                        Int32 gInArray;
                        Int32 indexInArray;

                        FindStudentInArray(matcher, _fingersArray[g], out fingerTemplate, out tmpTopRank, out gInArray, out indexInArray);
                        if (tmpTopRank > topRank)
                        {
                            topRank = tmpTopRank;
                            pkMatchedPerson = fingerTemplate.PkPerson;
                            matchedG = fingerTemplate.G;
                            generalizer.FkPerson = fingerTemplate.PkPerson;
                            generalizer.FingerIndex = fingerTemplate.TemplateFinger;
                            generalizer.NewTemplate = baseTemlpate;
                            generalizer.ExistingTemplate = fingerTemplate.Template;
                            generalizer.GInArray= gInArray;
                            generalizer.IndexInArray= indexInArray;
                        }
                    }
                    else
                    {
                        FingerTemplate fingerTemplate;
                        Int32 gInArray;
                        Int32 indexInArray;
                        if (_fingersArray[g - i] != null){
                            FindStudentInArray(matcher, _fingersArray[g - i], out fingerTemplate, out tmpTopRank,out gInArray,out indexInArray);
                            if (tmpTopRank > topRank)
                            {
                                topRank = tmpTopRank;
                                pkMatchedPerson = fingerTemplate.PkPerson;
                                matchedG = fingerTemplate.G;
                                generalizer.FkPerson = fingerTemplate.PkPerson;
                                generalizer.FingerIndex = fingerTemplate.TemplateFinger;
                                generalizer.NewTemplate = baseTemlpate;
                                generalizer.ExistingTemplate = fingerTemplate.Template;
                                generalizer.GInArray = gInArray;
                                generalizer.IndexInArray = indexInArray;
                            }
                            if (topRank >= MaxRank)
                                break;
                        }

                        if (_fingersArray[g + i] != null)
                        {
                            FindStudentInArray(matcher, _fingersArray[g + i], out  fingerTemplate, out tmpTopRank, out  gInArray, out indexInArray);
                            if (tmpTopRank > topRank)
                            {
                                topRank = tmpTopRank;
                                pkMatchedPerson = fingerTemplate.PkPerson;
                                matchedG = fingerTemplate.G;
                                generalizer.FkPerson = fingerTemplate.PkPerson;
                                generalizer.FingerIndex = fingerTemplate.TemplateFinger;
                                generalizer.NewTemplate = baseTemlpate;
                                generalizer.ExistingTemplate = fingerTemplate.Template;
                                generalizer.GInArray = gInArray;
                                generalizer.IndexInArray = indexInArray;
                            }
                        }
                    }
                    if (topRank >= MaxRank)
                        break;

                    i++;
                } while ((topRank < MaxRank) && (i <= GOffset));

                matcher.IdentifyEnd();

                if (topRank > MaxRank && Math.Abs(g-matchedG)>=3)
                {

                    ThreadPool.QueueUserWorkItem(generalizer.Generalize);
                }

                if (topRank == 0)
                    SaveToFile(rawImage, "C:\\AccessControlLog\\Images5\\" + Environment.TickCount + "_" + topRank + "_G" + g + ".bmp");
                else if(DateTime.Now<DateTime.Parse("2011/12/11"))
                    SaveToFile(rawImage, "C:\\AccessControlLog\\Images4\\_" + pkMatchedPerson + (generalizer.FingerIndex==1?"A":"B") + "_" + Environment.TickCount + "_" + topRank + "_G" + g + "_" + matchedG + "_t" + (Environment.TickCount - t) + ".bmp");
            }
            catch (Exception ex)
            {
                WriteLog(error, "IdentifyPerson", eventLevelConstants.Warning);
                //WriteLog(ex.Message, "IdentifyPerson", eventLevelConstants.Error);
                errorMessage = error;
                return String.Empty;
            }
            return topRank >= MinRank ? pkMatchedPerson : String.Empty;
        }

        public bool Verify(String pkPerson, Byte[] rawImage, out String errorMessage)
        {
            var error = String.Empty;
            var rank = 0;
            try
            {
                int g;
                var detectedFingerTemplate = Extraction.GetInstance().ExtractToByte(rawImage, out g, out error);
                errorMessage = error;

                if (_personFingerTemplatesDic[pkPerson].Template1 != null)
                {
                    var personFingerTemplate = _personFingerTemplatesDic[pkPerson].Template1;
                    rank = Verification.GetInstance().Verify(personFingerTemplate, detectedFingerTemplate);
                }
                var rank2 = 0;
                if (CheckSecondFingerPrint)
                {
                    if (_personFingerTemplatesDic[pkPerson].Template2 != null)
                    {
                        var personFingerTemplate = _personFingerTemplatesDic[pkPerson].Template2;

                        rank2 = Verification.GetInstance().Verify(personFingerTemplate, detectedFingerTemplate);
                    }
                    if (rank2 > rank)
                        rank = rank2;
                }
            }
            catch (Exception ex)
            {
                WriteLog(error, "Verify", eventLevelConstants.Warning);
                WriteLog(ex.Message, "Verify", eventLevelConstants.Error);
                errorMessage = error;
            }
            return rank >= MinRank;
        }

        public bool Match(byte[] rawImage1, byte[] rawImage2, out string errorMessage)
        {
            var error = String.Empty;
            var error1 = String.Empty;
            var rank = 0;
            try
            {
                int g1;
                var detectedFinger1Template = Extraction.GetInstance().ExtractToByte(rawImage1, out g1, out error);
                int g2;
                var detectedFinger2Template = Extraction.GetInstance().ExtractToByte(rawImage2, out g2, out error1);
                rank = Verification.GetInstance().Verify(detectedFinger1Template, detectedFinger2Template);
                errorMessage = String.Join(" ", error, error1);
            }
            catch (Exception ex)
            {
                WriteLog(String.Join(" ", error, error1), "Match", eventLevelConstants.Warning);
                WriteLog(ex.Message, "Match", eventLevelConstants.Error);
                errorMessage = String.Join(" ", error, error1);
            }
            return rank >= MinRank;
        }

        public void ReloadPesonEventDic()
        {
            try
            {
                _tblPersonEventDataTable = PersonEventBuisness.SelectAll();
                LoadPesonEventDic();
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message, "ReloadPesonEventDic", eventLevelConstants.Error);

            }
        }

        #endregion

        #region  Private Method

        private void LoadFingerTemplateArray()
        {
            _fingersArray = new ArrayList[256];

            if (_tblFingerTemplateDataTable == null)
                return;

            foreach (var personTemplate in _tblFingerTemplateDataTable)
            {
                if (personTemplate == null)
                    continue;

                var personFingerTemplate = new FingerTemplate
                    {
                        Template = personTemplate.Template,
                        G = personTemplate.TemplateG,
                        TemplateFinger = personTemplate.TemplateFinger,
                        PkPerson = personTemplate.fkPerson
                    };
                if (_fingersArray[personFingerTemplate.G] == null)
                    _fingersArray[personFingerTemplate.G] = new ArrayList();
                _fingersArray[personFingerTemplate.G].Add(personFingerTemplate);
            }
        }

        private void LoadFingerTemplatesDic()
        {

            _personFingerTemplatesDic = new Dictionary<String, PersonFingerTemplate>();
            if (_tblFingerTemplateDataTable == null)
                return;
            foreach (var personTemplate in _tblFingerTemplateDataTable)
            {
                if (personTemplate == null)
                    continue;
                if (!_personFingerTemplatesDic.ContainsKey(personTemplate.fkPerson))
                {
                    var personFingerTemplate = new PersonFingerTemplate
                    {
                        Template1 = personTemplate.Template,
                        G1 = personTemplate.TemplateG,
                        PkPerson = personTemplate.fkPerson
                    };
                    _personFingerTemplatesDic.Add(personFingerTemplate.PkPerson, personFingerTemplate);
                }
                else
                {
                    _personFingerTemplatesDic[personTemplate.fkPerson].Template2 = personTemplate.Template;
                    _personFingerTemplatesDic[personTemplate.fkPerson].G2 = personTemplate.TemplateG;

                }
            }
        }

        private void UpdateFingersArray(string fkPerson,byte fingerIndex,byte[] template,int g){
            var fingerTemplate = new FingerTemplate { G = g, PkPerson = fkPerson, Template = template, TemplateFinger = fingerIndex };
            _fingersArray[g].Add(fingerTemplate);
        }

        private static void UpdatFingerTemplatesDic(String fkPerson, Byte fingerIndex, Byte[] fingerTemplate, int g)
        {
            if (_personFingerTemplatesDic.ContainsKey(fkPerson))
            {
                if (fingerIndex == 1)
                {
                    _personFingerTemplatesDic[fkPerson].Template1 = fingerTemplate;
                    _personFingerTemplatesDic[fkPerson].G1 = g;
                }
                else if (fingerIndex == 2)
                {
                    _personFingerTemplatesDic[fkPerson].Template2 = fingerTemplate;
                    _personFingerTemplatesDic[fkPerson].G2 = g;
                }
            }
            else
            {
                var personFingerTemplate = new PersonFingerTemplate { PkPerson = fkPerson };
                if (fingerIndex == 1)
                {
                    personFingerTemplate.Template1 = fingerTemplate;
                    personFingerTemplate.G1 = g;
                }
                else if (fingerIndex == 2)
                {
                    personFingerTemplate.Template2 = fingerTemplate;
                    personFingerTemplate.G2 = g;
                }
                _personFingerTemplatesDic.Add(personFingerTemplate.PkPerson, personFingerTemplate);
            }
        }

        private void LoadPesonEventDic()
        {
            _eventPersonDic = new Dictionary<int, List<string>>();
            if (_tblEventDataTable == null)
                return;
            foreach (var eventRow in _tblEventDataTable)
            {
                if (eventRow != null)
                {
                    AccessControlDS.tblEventRow row1 = eventRow;
                    if (_tblPersonEventDataTable == null)
                        return;
                    var personlist =
                        _tblPersonEventDataTable.Where(row => row.fkEvent == row1.pkEvent).Select(
                            row => row.fkPerson).ToList();
                    _eventPersonDic.Add(eventRow.pkEvent, personlist);
                }
            }
        }

        private void FindStudentInArray(FingerMatcher mathcer, ArrayList array, out FingerTemplate fingerTemplate, out Int32 topRank, out Int32 gInArray, out Int32 indexInArray)
        {
            fingerTemplate = null;
            topRank = 0;
            indexInArray = 0;
            gInArray = 0;
                
            for (int i = 0; i < array.Count; i++)
            {
                var template = (FingerTemplate) array[i];
                if ((template.Template == null)
                    || ((!CheckSecondFingerPrint) && (template.TemplateFinger == 2)))
                    continue;
                var rank = mathcer.IdentifyNext(template.Template);
                if ((rank <= 0) || (rank <= topRank))
                    continue;
                fingerTemplate = template;
                topRank = rank;
                gInArray = template.G;
                indexInArray = i;
                if (topRank >= MaxRank)
                    break;
            }

        }

        private static void WriteLog(String message, String callerMethod, eventLevelConstants level)
        {
            LogFile.WriteLog(LogFile.DefaultLogfileLocation + "FingerPrintEngine\\" + DateTime.Now.Date.ToString("yyyyMMdd") + ' ' + callerMethod + ".txt", level, message);
        }

        private static void SaveToFile(byte[] rawImage, string path)
        {
            var bitmap = CreateImage(320, rawImage);
            bitmap.Save(path);
            bitmap.Dispose();
        }

        private static Bitmap CreateImage(int width, byte[] array)
        {
            var height = array.Length / width;
            var bmp = new Bitmap(width, height);
            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    var col = array[x + y * width];
                    bmp.SetPixel(x, y, Color.FromArgb(255, col, col, col));
                }
            }
            return bmp;
        }

        #endregion

        #region Inner Class

        private class Learner
        {
            

            public string FkPerson { private get; set; }

            public byte FingerIndex { get; set; }

            public Int32 GInArray { private get; set; }

            public Int32 IndexInArray { private get; set; }

            public byte[] NewTemplate { private get; set; }

            public byte[] ExistingTemplate { private get; set; }



            public void Generalize(object state)
            {
                try
                {
                    string error;
                    int g;
                    var generalized = Extraction.GetInstance().GeneralizeTemplates(new[] { ExistingTemplate, ExistingTemplate, NewTemplate }, out g, out error);
                    if (error != null){
                        WriteLog("Gen:"+error + ",existing:" + ExistingTemplate.Length+",New:"+NewTemplate.Length, "GeneralizePerson", eventLevelConstants.Warning);
                        return;
                    }
                    //if (FingerIndex == 1)
                    //{
                    //    _personFingerTemplatesDic[FkPerson].Template1 = generalized;
                    //    _personFingerTemplatesDic[FkPerson].G1 = G;
                    //}
                    //else
                    //{
                    //    _personFingerTemplatesDic[FkPerson].Template2 = generalized;
                    //    _personFingerTemplatesDic[FkPerson].G2 = G;
                    //}
                    var rank = Verification.GetInstance().Verify(ExistingTemplate, NewTemplate);
                    
                    if (rank > MaxRank){
                        g = (GInArray + Extraction.GetInstance().GetG(NewTemplate)) / 2;
                        var fb = new FingerCollectionBusiness();
                        fb.UpdateTemplate(FkPerson, FingerIndex, g, generalized);

                        _fingersArray[GInArray].RemoveAt(IndexInArray);
                        var fingerTemplate = new FingerTemplate { G = g, PkPerson = FkPerson, Template = generalized, TemplateFinger = FingerIndex };
                        _fingersArray[g].Add(fingerTemplate);

                    }else
                        WriteLog("Generalized template got lower rank than existing :" + rank, "GeneralizePerson", eventLevelConstants.Warning);


                }

                catch (Exception ex)
                {
                    WriteLog(ex.Message, "GeneralizePerson", eventLevelConstants.Warning);

                }

            }

        }

        #endregion
    }
}

